//go:build windows

package proc

import (
	"gitee.com/zhancaihua/goyt/core/logyt"
	"gitee.com/zhancaihua/goyt/core/threading"
	"os"
	"os/signal"
	"sync"
	"time"
)

const (
	wrapUpTime = time.Second
)

var (
	wrapUpListeners   = new(listenerManager)
	shutdownListeners = new(listenerManager)
)

// AddShutdownListener adds fn as a shutdown listener.
// The returned func can be used to wait for fn getting called.
func AddShutdownListener(fn func()) (waitForCalled func()) {
	return shutdownListeners.addListener(fn)
}

// gracefulStop windows下不用设置超时强制关闭机制
func gracefulStop(signals chan os.Signal) {
	signal.Stop(signals)

	logyt.InfoLog("Got signal SIGINT, shutting down...")
	go wrapUpListeners.notifyListeners()

	time.Sleep(wrapUpTime)
	go shutdownListeners.notifyListeners()
}

// AddWrapUpListener adds fn as a wrap up listener.
// The returned func can be used to wait for fn getting called.
func AddWrapUpListener(fn func()) (waitForCalled func()) {
	return wrapUpListeners.addListener(fn)
}

type listenerManager struct {
	lock      sync.Mutex
	waitGroup sync.WaitGroup
	listeners []func()
}

// addListener 添加监听器。返回的方法用于等待所有监听器执行完成
func (lm *listenerManager) addListener(fn func()) (waitForCalled func()) {
	lm.waitGroup.Add(1)

	lm.lock.Lock()
	lm.listeners = append(lm.listeners, func() {
		defer lm.waitGroup.Done()
		fn()
	})
	lm.lock.Unlock()

	return func() {
		lm.waitGroup.Wait()
	}
}

// notifyListeners 异步执行所有监听器，并等待所有监听器执行完成
func (lm *listenerManager) notifyListeners() {
	lm.lock.Lock()
	defer lm.lock.Unlock()

	group := threading.NewRoutineGroup()
	for _, listener := range lm.listeners {
		group.RunSafe(listener)
	}
	group.Wait()
}
